package com.ecocent.api;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.ecocent.api.helper.ClasspathResourceScanner;
import com.ecocent.api.helper.RestTemplateUtil;

public final class ApiContainer {
	private static final Logger LOG = LoggerFactory.getLogger(ApiContainer.class);

    private boolean init = false;
	private final static ApiContainer instance = new ApiContainer();

	private String loginName;
	private String password;
	private String loginUrl;
	private String apiModuleUrlsConfigFile;
	private ApiContext apiContext;
	private Map<String,Object> services = new HashMap<String,Object>();
	private RestTemplate restTemplate ;
	private Long loginTime=0L;
	public String getLoginName() {
		return loginName;
	}
	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getLoginUrl() {
		return loginUrl;
	}
	public void setLoginUrl(String loginUrl) {
		this.loginUrl = loginUrl;
	}
	public String getApiModuleUrlsConfigFile() {
		return apiModuleUrlsConfigFile;
	}
	public void setApiModuleUrlsConfigFile(String apiModuleUrlsConfigFile) {
		this.apiModuleUrlsConfigFile = apiModuleUrlsConfigFile;
	}
	public Object getServiceByKey(String key){
		return services.get(key);
	}
	public void register(String key,Object object){
		services.put(key, ProxyUtil.getProxy(object));
	}
	public static ApiContainer getInstance()
    {
    	return instance;
    }
	private  synchronized void  initContainer() throws Exception
    {
    	if(!init)
    	{
    	    Properties propertes = new Properties();
    		try {
    			List<URL> files = ClasspathResourceScanner.scan(apiModuleUrlsConfigFile);
    			if(files!=null && files.size()>0){
    				propertes.load(files.get(0).openStream());
    			}else{
        			propertes.load(new FileInputStream(new File(apiModuleUrlsConfigFile)));
    			}
    		} catch (FileNotFoundException e) {
    			LOG.error("The file ("+apiModuleUrlsConfigFile+") is not instanced to FileInputStream.",e);
    		} catch (IOException e) {
    			LOG.error("An error occurs during loading the  file "+apiModuleUrlsConfigFile+".",e);
    		}					
    		apiContext = new ApiContextImpl(propertes);
    		restTemplate = RestTemplateUtil.getRestTemplate();
    		new ApiProviderNotifier(apiContext).notifyProvider();
    		init = true;
    	}
    }
	public RestTemplate getRestTemplate(){
		return restTemplate;
	}
	public void refreshLogin() {
		synchronized(this){
			Long time = new Date().getTime();
			//不需要刷新太频繁，10秒内不刷新
			if((time-this.loginTime)>10000){
		        MultiValueMap<String, String> requestEntity = new LinkedMultiValueMap<>();
                requestEntity.add("loginName", this.getLoginName());
                requestEntity.add("password", this.getPassword());
                BaseResult result = restTemplate.postForObject(this.getLoginUrl(), requestEntity, BaseResult.class);
		        if(Constants.LOGININFO_ERROR_STATUS_CODE == result.getStatuscode()){
		        	LOG.error("api链接用户名密码错误，请配置正确的用户名密码"); 
		        	throw new RuntimeException("api链接用户名密码错误，请配置正确的用户名密码");
		        }
		        this.loginTime = new Date().getTime();
			}
		}
		
	}
}
